package cn.wolfcode.shop.service;

import cn.wolfcode.qo.PageResult;
import cn.wolfcode.shop.domain.*;
import cn.wolfcode.shop.exception.OrderException;
import cn.wolfcode.shop.exception.UserException;
import cn.wolfcode.shop.mapper.InvoiceMapper;
import cn.wolfcode.shop.mapper.OrderActionMapper;
import cn.wolfcode.shop.mapper.OrderInfoMapper;
import cn.wolfcode.shop.mapper.OrderProductMapper;
import cn.wolfcode.shop.qo.OrderQueryObject;
import cn.wolfcode.shop.vo.OrderStatusChangeVo;
import cn.wolfcode.shop.vo.OrderVo;
import cn.wolfcode.util.IdGenerateUtil;
import cn.wolfcode.util.RedisConstants;
import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.dubbo.config.annotation.Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
@Transactional
public class OrderInfoServiceImpl implements IOrderInfoService {

    @Autowired
    private InvoiceMapper invoiceMapper;
    @Autowired
    private OrderInfoMapper orderInfoMapper;
    @Autowired
    private OrderProductMapper orderProductMapper;
    @Autowired
    private OrderActionMapper orderActionMapper;
    @Reference
    private IUserAddressService userAddressService;
    @Autowired
    private RedisTemplate redisTemplate;

    @Override
    public OrderInfo generateOrder(Long userId, OrderVo orderVo) {

        //创建订单对象，设置用户id
        OrderInfo orderInfo = new OrderInfo();
        orderInfo.setUserId(userId);

        //生成订单编号,通过工具类获取唯一的编号
        orderInfo.setOrderSn(IdGenerateUtil.get().nextId() + "");

        //通过用户收货地址id获取用户收货地址对象，并把相关的地址信息设置到订单信息中
        UserAddress userAddress = userAddressService.get(orderVo.getUserAddressId());
        orderInfo.setAddress(userAddress.getAddress());
        orderInfo.setCity(userAddress.getCity());
        orderInfo.setConsignee(userAddress.getConsignee());
        orderInfo.setPhone(userAddress.getPhone());
        orderInfo.setCountry(userAddress.getCountry());
        orderInfo.setProvince(userAddress.getProvince());
        orderInfo.setDistrict(userAddress.getDistrict());
        orderInfo.setAddress(userAddress.getAddress());
        orderInfo.setZipcode(userAddress.getZipcode());

        //设置订单的其他信息，比如订单状态，收货状态，物流状态，下单时间等
        orderInfo.setOrderTime(new Date());
        orderInfo.setOrderStatus(0);
        orderInfo.setFlowStatus(0);
        orderInfo.setPayStatus(0);
        //支付类型从前台传过来
        orderInfo.setPayType(orderVo.getPay().getPayType());
        //设置订单总金额, 要先去获取订单产品的价格


        //获取购物车商品列表遍历，并生成订单商品明细
        String shopCarKey;
        ShopCar shopCar;
        OrderProduct orderProduct;
        List<OrderProduct> orderProductList = new ArrayList();
        orderInfo.setOrderAmount(new BigDecimal(0));
        //通过skuId获取sku对象，并设置价格
        //遍历sku属性集合，并设置到订单商品明细属性对象中，插入该订单商品明细属性数据
        for (Long skuId : orderVo.getSkuIds()) {
            shopCarKey = MessageFormat.format(RedisConstants.SHOPCAR_ITEM, userId, skuId);
            shopCar = (ShopCar) redisTemplate.opsForValue().get(shopCarKey);
            if (shopCar == null) {
                throw new OrderException("参数异常");
            }
            //shopCar的信息转移到订单商品明细中
            orderProduct = new OrderProduct();
            orderProduct.setProductImg(shopCar.getProductImage());
            orderProduct.setProductName(shopCar.getProductName());
            orderProduct.setProductNumber(shopCar.getNumber());
            orderProduct.setProductPrice(shopCar.getPrice());
            orderProduct.setSkuId(shopCar.getProductSkuId());
            orderProduct.setSkuType(shopCar.getSkuPropertyString());
            //计算订单商品明细中的商品小计
            //产品总价格:商品数量*单价
            orderProduct.setTotalPrice(orderProduct.getProductNumber().multiply(orderProduct.getProductPrice()));


            //插入该订单商品明细
            orderProductList.add(orderProduct);//把所有的订单商品明细存在list中

            //把订单商品明细中的商品小计累加到订单总额中
            orderInfo.setOrderAmount(orderInfo.getOrderAmount().add(orderProduct.getTotalPrice()));
            System.out.println(orderInfo.getOrderAmount());
        }
        //插入该订单
        orderInfoMapper.insert(orderInfo);

        for (OrderProduct product : orderProductList) {
            product.setOrderId(orderInfo.getId());
            orderProductMapper.insert(product);
        }


        //判断是否需要开发票，如果要则,设置发票人和发票对应的订单，并插入发票信息
        if (orderVo.getInvoice() != null) {
            orderVo.getInvoice().setOrderId(orderInfo.getId());
            orderVo.getInvoice().setUserId(userId);
            invoiceMapper.insert(orderVo.getInvoice());
        }

        //记录订单的操作日志
        createOrderAction("创建订单", orderInfo, "后台", "后台管理员");


        //判断有无购物车id，如果有则删除购物车信息
        String shopCarListKey = MessageFormat.format(RedisConstants.SHOPCAR_LIST, userId);
        for (Long skuId : orderVo.getSkuIds()) {
            //获取shopCarkey 再删除
            shopCarKey = MessageFormat.format(RedisConstants.SHOPCAR_ITEM, userId, skuId);
            redisTemplate.delete(shopCarKey);
            redisTemplate.opsForList().remove(shopCarListKey, 1, skuId);
        }

        return orderInfo;
    }

    @Override
    public PageResult query(OrderQueryObject qo) {
        int count = orderInfoMapper.queryCount(qo);
        if (count == 0) {
            return PageResult.empty();
        }
        List<OrderInfo> orderInfoList = orderInfoMapper.queryList(qo);

        return new PageResult(orderInfoList, count, qo.getCurrentPage(), qo.getPageSize());
    }

    @Override
    public OrderInfo getById(Long id) {
        return orderInfoMapper.selectByPrimaryKey(id);
    }

    @Override
    public void changeStatus(Long orderId, Integer changeType, String note) {
        OrderInfo orderInfo = orderInfoMapper.selectByPrimaryKey(orderId);
        if (orderInfo == null) {
            throw new UserException("非法操作");
        }
        switch (changeType) {
            case 1:
                orderInfo.setOrderStatus(1);
                break;
            case 2:
                orderInfo.setFlowStatus(1);
                break;
            case 3:
                orderInfo.setFlowStatus(4);
                break;
            case 4:
                System.out.println("请联系售后");
                break;
            default:
                System.out.println("请联系售后");
                break;
        }

        orderInfoMapper.updateByPrimaryKey(orderInfo);
        //记录订单的操作日志
        createOrderAction(note, orderInfo, "后台", "后台管理员");

    }

    @Override
    public OrderInfo changeStatus(OrderStatusChangeVo orderStatusChangeVo) {

        OrderInfo orderInfo = orderInfoMapper.selectByPrimaryKey(orderStatusChangeVo.getOrderId());
        if (orderInfo == null) {
            throw new UserException("非法操作");
        }
        switch (orderStatusChangeVo.getChangeType()) {
            case 5:
                orderInfo.setOrderStatus(2);
                orderInfo.setFlowStatus(2);
                break;
            default:
                System.out.println("请联系售后");
                break;
        }

        orderInfoMapper.updateByPrimaryKey(orderInfo);
        //记录订单的操作日志
        createOrderAction(orderStatusChangeVo.getNote(), orderInfo, "前台", orderStatusChangeVo.getUserName());
        return orderInfo;

    }


    public void createOrderAction(String note, OrderInfo orderInfo, String place, String user) {
        OrderAction orderAction = new OrderAction();
        orderAction.setActionNote(note);
        orderAction.setActionPlace(place);
        orderAction.setActionTime(new Date());
        orderAction.setActionUser(user);
        orderAction.setFlowStatus(orderInfo.getFlowStatus());
        orderAction.setOrderStatus(orderInfo.getOrderStatus());
        orderAction.setPayStatus(orderInfo.getPayStatus());
        orderAction.setOrderId(orderInfo.getId());
        orderActionMapper.insert(orderAction);
    }
}
